package main

import (
	"context"
	"flag"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"nettools/client/config"
	"nettools/client/forwarder"
	"nettools/shared/utils"
)

var (
	configFile = flag.String("config", "configs/client-internal.json", "配置文件路径")
	mode       = flag.String("mode", "", "工作模式: internal/external (覆盖配置文件设置)")
	version    = flag.Bool("version", false, "显示版本信息")
)

const (
	AppName    = "NetTools Client"
	AppVersion = "1.0.0"
)

// Client 客户端接口
type Client interface {
	Start() error
	Stop() error
	GetSessionCount() int
}

func main() {
	// 检查命令行参数
	var configPath string
	if len(os.Args) >= 2 {
		configPath = os.Args[1]
	} else {
		configPath = "configs/config.json"
		utils.Info("未指定配置文件，使用默认配置: %s", configPath)
	}

	utils.Info("🚀 启动NetTools客户端")
	utils.Info("配置文件: %s", configPath)

	// 加载配置文件
	cfg, err := config.LoadConfig(configPath)
	if err != nil {
		log.Fatalf("❌ 加载配置文件失败: %v", err)
	}

	// 根据模式创建不同类型的客户端
	var client Client
	switch cfg.Mode {
	case "internal":
		client = forwarder.NewInternalClient(cfg)
		utils.Info("📡 内网客户端模式")
	case "external":
		client = forwarder.NewExternalClient(cfg)
		utils.Info("🌐 外网客户端模式")
	default:
		log.Fatalf("❌ 不支持的客户端模式: %s", cfg.Mode)
	}

	// 设置信号处理
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	// 启动客户端
	if err := client.Start(); err != nil {
		log.Fatalf("❌ 启动客户端失败: %v", err)
	}

	// 输出启动信息
	utils.Info("🎯 客户端已启动，按 Ctrl+C 停止...")
	utils.Info("📋 客户端信息:")
	utils.Info("   - 客户端ID: %s", cfg.ClientID)
	utils.Info("   - 模式: %s", cfg.Mode)
	utils.Info("   - 服务数量: %d", len(cfg.Services))

	// 输出服务详情
	for i, service := range cfg.Services {
		if cfg.Mode == "internal" {
			utils.Info("   服务[%d]: %s (服务器端口: %d -> 本地: %s:%d)",
				i+1, service.Name, service.ServerPort, service.TargetHost, service.TargetPort)
		} else {
			utils.Info("   服务[%d]: %s (本地端口: %d -> 服务器端口: %d)",
				i+1, service.Name, service.LocalPort, service.ServerPort)
		}
	}

	// 启动状态监控
	go startStatusMonitor(client, cfg.Mode)

	// 等待信号
	select {
	case sig := <-sigChan:
		utils.Info("📝 接收到信号: %v", sig)
	case <-ctx.Done():
		utils.Info("📝 上下文取消")
	}

	// 优雅关闭
	utils.Info("🛑 正在优雅关闭客户端...")
	if err := client.Stop(); err != nil {
		log.Printf("❌ 关闭客户端时出错: %v", err)
	}

	utils.Info("👋 客户端已成功关闭")
}

// startStatusMonitor 启动状态监控
func startStatusMonitor(client Client, mode string) {
	ticker := time.NewTicker(30 * time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			sessionCount := client.GetSessionCount()
			if mode == "internal" {
				utils.Info("📊 状态监控 - 活跃会话: %d", sessionCount)
			} else {
				utils.Info("📊 状态监控 - 代理会话: %d", sessionCount)
			}
		}
	}
}
